import json
import requests
import sys
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
                             QWidget, QPushButton, QTextEdit, QLabel, QMessageBox)
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtGui import QFont
from datetime import datetime, timedelta


class DataFetcher(QThread):
    """数据获取线程"""
    finished = pyqtSignal(bool, str)
    progress = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.headers = {
            "accept": "application/json, text/plain, */*",
            "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,ar;q=0.7",
            "cache-control": "no-cache",
            "origin": "https://xuangutong.com.cn",
            "pragma": "no-cache",
            "priority": "u=1, i",
            "referer": "https://xuangutong.com.cn/dingpan",
            "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "\"Windows\"",
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "cross-site",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0"
        }
        self.url = "https://flash-api.xuangubao.com.cn/api/pool/detail"
        self.params = {"pool_name": "limit_up"}

    def is_st_stock(self, name):
        """判断是否为ST股票"""
        return name.upper().startswith('ST') or name.upper().startswith('*ST')

    def run(self):
        try:
            all_limit_up_data = []

            self.progress.emit("正在获取数据...")
            current_date = datetime.now()

            for i in range(5):  # 获取最近5天的数据
                date = (current_date - timedelta(days=i)).strftime("%Y-%m-%d")
                self.params["date"] = date
                response = requests.get(self.url, headers=self.headers, params=self.params)
                response.raise_for_status()

                self.progress.emit(f"正在解析 {date} 的数据...")
                data = response.json()

                if not data or "data" not in data or not data["data"]:
                    continue

                all_limit_up_data.extend(data["data"])

            plate_count = {}
            limit_up_numbers = []
            limit_up_reasons = []
            plate_to_index = {}

            # 创建板块索引
            for item in all_limit_up_data:
                if self.is_st_stock(item.get("stock_chi_name", "")):
                    continue

                related_plates = item.get("surge_reason", {}).get("related_plates", [])
                for plate in related_plates:
                    plate_name = plate.get("plate_name", "")
                    if plate_name and plate_name != "ST股":
                        plate_count[plate_name] = plate_count.get(plate_name, 0) + 1

            # 创建板块索引
            normal_plates = sorted(plate_count.keys(), key=lambda x: plate_count[x], reverse=True)
            plate_to_index = {plate: idx + 1 for idx, plate in enumerate(normal_plates)}

            # 处理每只股票数据
            for item in all_limit_up_data:
                if self.is_st_stock(item.get("stock_chi_name", "")):
                    continue

                raw_symbol = item.get("symbol", "")
                symbol = raw_symbol.split('.')[0] if raw_symbol else ""

                related_plates = item.get("surge_reason", {}).get("related_plates", [])
                plate_indices = []

                # 收集板块索引
                for plate in related_plates:
                    plate_name = plate.get("plate_name", "")
                    if plate_name in plate_to_index:
                        plate_indices.append(plate_to_index[plate_name])

                if plate_indices:
                    indices_str = '.'.join(map(str, plate_indices))
                    limit_up_numbers.append((symbol, indices_str))

                    reasons_str = ' '.join(plate.get("plate_name", "") for plate in related_plates)
                    limit_up_reasons.append((symbol, reasons_str))

            # 保存涨停数字到txt文件
            with open("涨停数字.txt", "w", encoding="gbk") as f:
                for symbol, indices in limit_up_numbers:
                    f.write(f"{symbol}\t{indices}\n")

            # 保存涨停理由到文件
            with open("涨停理由.txt", "w", encoding="gbk") as f:
                for symbol, reason in limit_up_reasons:
                    f.write(f"{symbol}\t{reason}\n")

            # 保存板块索引到文件
            with open("板块索引.txt", "w", encoding="gbk") as f:
                for i, plate_name in enumerate(normal_plates, 1):
                    f.write(f"{i}\t{plate_name}\n")

            success_msg = f"数据获取成功！共处理了 {len(limit_up_numbers)} 只涨停股票（已排除ST股票）"
            self.finished.emit(True, success_msg)

        except requests.exceptions.RequestException as e:
            self.finished.emit(False, f"请求失败：{e}")
        except json.JSONDecodeError as e:
            self.finished.emit(False, f"JSON解析失败：{e}")
        except Exception as e:
            self.finished.emit(False, f"发生错误：{e}")


class StockAnalyzer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.data_fetcher = None

    def initUI(self):
        self.setWindowTitle('股票涨停数据分析器')
        self.setGeometry(100, 100, 1200, 800)

        # 创建中心部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # 创建主布局
        main_layout = QVBoxLayout()
        central_widget.setLayout(main_layout)

        # 创建顶部按钮区域
        top_layout = QHBoxLayout()

        # 获取数据按钮
        self.fetch_btn = QPushButton('获取涨停数据')
        self.fetch_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 10px;
                font-size: 14px;
                font-weight: bold;
                border-radius: 5px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:pressed {
                background-color: #3d8b40;
            }
        """)
        self.fetch_btn.clicked.connect(self.fetch_data)
        top_layout.addWidget(self.fetch_btn)

        # 添加弹性空间
        top_layout.addStretch()

        main_layout.addLayout(top_layout)

        # 创建中部按钮区域
        middle_layout = QHBoxLayout()

        # 查看按钮
        self.view_numbers_btn = QPushButton('查看涨停数字')
        self.view_reasons_btn = QPushButton('查看涨停理由')
        self.view_plates_btn = QPushButton('查看板块索引')

        # 设置按钮样式
        button_style = """
            QPushButton {
                background-color: #2196F3;
                color: white;
                border: none;
                padding: 8px 16px;
                font-size: 12px;
                border-radius: 4px;
                margin: 2px;
            }
            QPushButton:hover {
                background-color: #1976D2;
            }
            QPushButton:pressed {
                background-color: #1565C0;
            }
            QPushButton:disabled {
                background-color: #CCCCCC;
                color: #666666;
            }
        """

        self.view_numbers_btn.setStyleSheet(button_style)
        self.view_reasons_btn.setStyleSheet(button_style)
        self.view_plates_btn.setStyleSheet(button_style)

        # 初始状态禁用查看按钮
        self.view_numbers_btn.setEnabled(False)
        self.view_reasons_btn.setEnabled(False)
        self.view_plates_btn.setEnabled(False)

        # 连接按钮事件
        self.view_numbers_btn.clicked.connect(lambda: self.view_file('涨停数字.txt'))
        self.view_reasons_btn.clicked.connect(lambda: self.view_file('涨停理由.txt'))
        self.view_plates_btn.clicked.connect(lambda: self.view_file('板块索引.txt'))

        middle_layout.addWidget(self.view_numbers_btn)
        middle_layout.addWidget(self.view_reasons_btn)
        middle_layout.addWidget(self.view_plates_btn)
        middle_layout.addStretch()

        main_layout.addLayout(middle_layout)

        # 创建文本显示区域
        self.text_display = QTextEdit()
        self.text_display.setFont(QFont("Courier New", 10))
        self.text_display.setReadOnly(True)
        self.text_display.setStyleSheet("""
            QTextEdit {
                background-color: #f5f5f5;
                border: 1px solid #ddd;
                border-radius: 4px;
                padding: 8px;
            }
        """)
        self.text_display.setPlainText("请先获取数据，然后点击查看按钮来查看不同类型的数据...")

        main_layout.addWidget(self.text_display)

        # 创建状态栏
        self.status_label = QLabel('就绪')
        self.status_label.setStyleSheet("""
            QLabel {
                background-color: #f0f0f0;
                border: 1px solid #ccc;
                padding: 5px;
                border-radius: 3px;
            }
        """)
        main_layout.addWidget(self.status_label)

        # 设置窗口居中
        self.center()

    def center(self):
        """窗口居中"""
        screen = QApplication.desktop().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)

    def fetch_data(self):
        """获取数据"""
        self.fetch_btn.setEnabled(False)
        self.fetch_btn.setText('正在获取数据...')

        # 禁用查看按钮
        self.view_numbers_btn.setEnabled(False)
        self.view_reasons_btn.setEnabled(False)
        self.view_plates_btn.setEnabled(False)

        # 创建并启动数据获取线程
        self.data_fetcher = DataFetcher()
        self.data_fetcher.progress.connect(self.update_status)
        self.data_fetcher.finished.connect(self.on_data_fetched)
        self.data_fetcher.start()

    def update_status(self, message):
        """更新状态"""
        self.status_label.setText(message)

    def on_data_fetched(self, success, message):
        """数据获取完成"""
        self.fetch_btn.setEnabled(True)
        self.fetch_btn.setText('获取涨停数据')

        if success:
            self.status_label.setText(message)
            # 启用查看按钮
            self.view_numbers_btn.setEnabled(True)
            self.view_reasons_btn.setEnabled(True)
            self.view_plates_btn.setEnabled(True)

            # 显示成功消息
            QMessageBox.information(self, '成功',
                                    message + '\n\n文件已保存：\n- 涨停数字.txt\n- 涨停理由.txt\n- 板块索引.txt')

            # 默认显示涨停数字
            self.view_file('涨停数字.txt')
        else:
            self.status_label.setText(f'错误: {message}')
            QMessageBox.critical(self, '错误', message)

    def view_file(self, filename):
        """查看文件内容"""
        try:
            if not os.path.exists(filename):
                QMessageBox.warning(self, '警告', f'文件 {filename} 不存在，请先获取数据')
                return

            with open(filename, 'r', encoding='gbk') as f:
                content = f.read()

            title = f"========== {filename} ==========\n\n"
            self.text_display.setPlainText(title + content)

            # 更新状态
            self.status_label.setText(f'正在查看: {filename}')

            # 移动光标到顶部
            cursor = self.text_display.textCursor()
            cursor.movePosition(cursor.Start)
            self.text_display.setTextCursor(cursor)

        except Exception as e:
            QMessageBox.critical(self, '错误', f'读取文件失败: {e}')
            self.status_label.setText(f'读取文件失败: {e}')


def main():
    app = QApplication(sys.argv)
    app.setStyle('Fusion')  # 使用Fusion样式

    # 设置应用程序样式
    app.setStyleSheet("""
        QMainWindow {
            background-color: #f0f0f0;
        }
        QWidget {
            font-family: "微软雅黑", "Arial", sans-serif;
        }
    """)

    analyzer = StockAnalyzer()
    analyzer.show()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()